package cn.tedu.charging.device.warm;

import cn.tedu.charging.common.pojo.po.ChargingStationPO;
import cn.tedu.charging.device.mapper.StationMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 这个类可以实现 整个应用程序 对应设备数据
 * 所有所需的预热数据加载
 */
@Component
@Slf4j
//@Order(100)
public class WarmUpStarter implements ApplicationRunner {
    @Autowired
    private StationMapper stationMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("缓存预热开始执行");
        //1.读取数据库表格 charging_stations select * from charging_stations
        List<ChargingStationPO> stationPos=getAllStations();
        //2.写入redis缓存
        saveGeoStationId(stationPos);
    }

    private void saveGeoStationId(List<ChargingStationPO> stationPos) {
        //1.key=charging:stations:all 放到common的常量中 最合理的
        String key="charging:stations:all";
        //2.geoadd lng1 lat1 id1 lng2 lat2 id2 .... 节省网络往返时间 一次性写入多个元素
        //2.1 拿到操作geo客户端子对象
        GeoOperations geoOps = redisTemplate.opsForGeo();
        //2.2 组织一个List<GeoLocation> 集合一次性写入 stream().map
        List<RedisGeoCommands.GeoLocation> geoLocations=new ArrayList<>();
        for (ChargingStationPO po : stationPos) {
            Integer member = po.getId();
            double xLng = po.getStationLng().doubleValue();
            double yLat = po.getStationLat().doubleValue();
            RedisGeoCommands.GeoLocation geoLocation =
                    new RedisGeoCommands.GeoLocation<>(member, new Point(xLng, yLat));
            geoLocations.add(geoLocation);
        }
//            //映射计算过程 stationPo 变成GeoLocation的过程
//            Integer member = po.getId();
//            double xLng = po.getStationLng().doubleValue();
//            double yLat = po.getStationLat().doubleValue();
//            RedisGeoCommands.GeoLocation geoLocation = new RedisGeoCommands.GeoLocation<>(member, new Point(xLng, yLat));
//            //将计算结果返回
//            return geoLocation;
//        }).collect(Collectors.toList());
        //2.3调用redis客户端api写入redis
        geoOps.add(key,geoLocations);
    }

    private List<ChargingStationPO> getAllStations() {
        //charging_stations select * from charging_stations
        return stationMapper.selectList(null);
    }

}
